classdef Processor_dev < handle
  % Base class for SBE Data Procesing functions
  % Derived from handle
  % Constructor signature: proc = Processor_dev(data), argument optional
  %
  % Author: David Goldsmith, Wash. State Dept. of Ecology, dgol461@ecy.wa.gov
  % Release date: N/A
  
    properties
        inData;
        castDT;
        scanRate;
        ParamID;
        ParamDesc;
        SBEprec;
        EquipID;
    end
    
    methods
        function proc = Processor_dev(data) % Constructor
            global instHeaderData
            if ~nargin, data = []; end
            proc.inData = data;
            proc.castDT = instHeaderData.castDatetime;
            proc.scanRate = instHeaderData.scanRate;
        end
        
        function getDBdata(obj, conn, type)
            if ~isempty(obj.inData)
                q = query_dev(conn, struct('tbls', {{'Parameter'}},...
                                           'cols', {{'ParameterID',...
                                                     'ParameterDescription',...
                                                     'SBEPrecision'}},...
                                           'where',...
                                           {{['MatlabProcessingID=''' type '''']}}));
                q.submitStatement
            end
            if isempty(obj.inData) || isempty(q.result)
                obj.ParamID = NaN;
                obj.ParamDesc = '';
                obj.SBEprec = NaN;
            else
                obj.ParamID = q.result{1};
                obj.ParamDesc = q.result{2};
                obj.SBEprec = q.result{3};
            end
            
            if isprop(obj.inData, 'Sensors')
                q.setPropVals('tbls', {'Equipment'});
                q.setPropVals('cols', {'EquipmentID'});
                try
                    if ~isfield(obj.inData.Sensors, [obj.ParamDesc 'Sensor'])
                        fns = fieldnames(obj.inData.Sensors);
                        fns = cellfun(@regexprep, fns,...
                                      constCellArr('Sensor', size(fns)),...
                                      constCellArr('', size(fns)),...
                                      'UniformOutput',0);
                        pd = cellfun(@regexp, constCellArr(obj.ParamDesc,...
                                                           size(fns)),...
                                              fns, 'UniformOutput', 0);
                        obj.ParamDesc = fns{~cellfun(@isempty, pd)};
                    end
                    SN = eval(['obj.inData.Sensors.' obj.ParamDesc ...
                                                   'Sensor.SerialNumber']);
                    if isnumeric(SN), SN = num2str(SN); end
                    if size(SN,1) > 1, SN = SN'; end
                    q.setPropVals('where', {['SerialNumberDescription=''' SN '''']});
                    q.submitStatement
                    if isnumeric(q.result{:})
                        obj.EquipID = q.result{1};
                    else
                        obj.EquipID = NaN;
                    end
                catch ME
                    if any(~isempty(regexp(ME.message,...
                                           {'Unexpected MATLAB expression',...
                                            'Reference to non-existent field'},...
                                            'once')))
                        obj.EquipID = NaN; % Default for params w/ no EquipID
                    else
                        rethrow(ME);
                    end
                end
            end
            
            j = injoinQuery_dev(conn, struct.empty);
            j.setPropVals('tbls', {'Global', 'GlobalType'})
            j.setPropVals('cols', {'UTCGlobalBeginDateTime', 'GlobalTypeName', 'GlobalQuantity'})
            if isempty(obj.inData)
                j.setPropVals('cols', {'ApplicableParameters'}, 1)
            end
            j.setPropVals('on', {'GlobalTypeID'})
            j.setPropVals('where', {['GlobalType.GlobalTypeName like ''' type '%''']})
            j.submitStatement
            if ismember({'No Data'}, j.result(cellfun(@ischar, j.result)))
                obj.DBdata = {};
            else
                obj.dateValidateData(j.result);
            end
        end
        
        function dateValidateData(obj, jResult)
            if iscell(jResult)
                numRes = numel(jResult(1,:));
                for i=1:numel(jResult(:,1))
                    fieldName = convert2ValidVariable(jResult{i,2});
                    if obj.castDT > datenum(jResult{i,1}(1:end-7))
                        if numRes==4
                            obj.DBdata.(fieldName) = jResult(i,3:4);
                        else
                            obj.DBdata.(fieldName) = jResult{i,3};
                        end
                    else
                        obj.DBdata.(fieldName) = 'date invalid';
                    end
                end
            elseif ischar(jResult)
                dt = jResult';
                if ~isDateTime(dt)
                    if isDateTime(dt(1:end-1))
                        dt = dt(1:end-1);
                    else
                        obj.('dateValid') = false;
                        return
                    end
                end                        
                obj.('dateValid') = (obj.castDT > datenum(dt));
            end
        end
        
        function delete(obj)
        end
        
    end
    
    methods (Abstract)
        mainFormula(obj);
    end

end